﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace CalculatorLogic
{
    /// <summary>
    /// An object representing a 2d space, with an x and y axis, intervals and an equation
    /// </summary>
    public class Graph
    {
        #region fields

        /// <summary>
        /// the int number of axes the graph has, should be 2
        /// </summary>
        int axesCount;

        /// <summary>
        /// the graph has an x axis
        /// </summary>
        Axis xAxis;
        /// <summary>
        /// the graph has an y axis
        /// </summary>
        
        Axis yAxis;

        

        /// <summary>
        /// a list of Axis objects the graph contains
        /// </summary>
        List<Axis> axes;

        /// <summary>
        /// the x axis width of the graph, the screen representation of width
        /// </summary>
        double xWidth;

        /// <summary>
        /// the x axis height of the graph, the screen representation of height
        /// </summary>
        double xHeight;

        /// <summary>
        /// the minimal x value to show on screen, could be negative or positive
        /// </summary>
        double xMin;

        /// <summary>
        /// the maximal x value to show on screen, should be positive but doesn't have to be
        /// </summary>
        double xMax;

        /// <summary>
        /// the scale of the x axis, this is used to determine how far markers are placed
        /// </summary>
        double xScale;

        /// <summary>
        /// the minimal y value to show on screen, could be positive or negative
        /// </summary>
        double yMin;

        /// <summary>
        /// the maximal y value to show on screen, should be positive
        /// </summary>
        double yMax;

        /// <summary>
        /// the scale of the y axis, this is used to determine how far markers are placed
        /// </summary>
        double yScale;

        /// <summary>
        /// the y axis width of the graph, should be small 1 or 2
        /// </summary>
        double yWidth;
        /// <summary>
        /// the y axis height of the graph
        /// </summary>
        double yHeight;

        /// <summary>
        /// the collection of GraphInterval structs for the graph, along both the x and y axis
        /// </summary>
        List<GraphInterval> graphIntervals;

        /// <summary>
        /// a bool for whether the graph should be drawn, since more than one equation can be shown on a graph
        /// </summary>
        bool enabled = false;

        /// <summary>
        /// The center of the graph or origin
        /// </summary>
        Point centerPoint;

        #endregion fields

        #region Properties
        /// <summary>
        /// Get the graph's XAxis
        /// </summary>
        public Axis XAxis
        {
            get { return xAxis; }
            
        }

        /// <summary>
        /// Get the graph's YAxis
        /// </summary>
        public Axis YAxis
        {
            get { return yAxis; }
            
        }
        /// <summary>
        /// Get the Width of the X Axis
        /// </summary>
        public double XWidth
        {
            get { return xWidth; }
        }
        /// <summary>
        /// Get the height of the X Axis
        /// </summary>
        public double XHeight
        {
            get { return xHeight; }
        }

        /// <summary>
        /// Get the width of the Y Axis
        /// </summary>
        public double YWidth
        {
            get { return yWidth; }
        }

        /// <summary>
        /// Get the height of the Y Axis
        /// </summary>
        public double YHeight
        {
            get { return yHeight; }
        }

        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

        public List<GraphInterval> GraphIntervals
        {
            get { return graphIntervals; }
        }

        /// <summary>
        /// Get or set the center or origin of the graph
        /// </summary>
        public Point CenterPoint
        {
            get { return centerPoint; }
            set { centerPoint = value; }
        }

        #endregion Properties

        #region Constructors
        /// <summary>
        /// Constructor for creating the graph object
        /// </summary>
        /// <param name="xWidth">the width of the x axis </param>
        /// <param name="xHeight">the height of the x axis</param>
        /// <param name="yWidth">the width of the y axis</param>
        /// <param name="yHeight">the height of the y axis</param>
        /// <param name="centerPoint">the center or origin of the graph</param>
        public Graph(double xWidth, double xHeight, double yWidth, double yHeight, Point centerPoint)
        {
            this.xWidth = xWidth;
            this.xHeight = xHeight;
            this.yWidth = yWidth;
            this.yHeight = yHeight;
            this.centerPoint = centerPoint;
        }

        /// <summary>
        /// Contstructor for creating a graph from an equation
        /// </summary>
        /// <param name="xWidth">the width of the x axis</param>
        /// <param name="xHeight">the height of the x axis</param>
        /// <param name="yWidth">the width of the y axis</param>
        /// <param name="yHeight">the height of the y axis</param>
        /// <param name="equation">the equation for the graph</param>
        public Graph(double xWidth, double xHeight, double yWidth, double yHeight, Point centerPoint, Equation equation)
        {
            //set fields in here
        }

        public Graph(Axis xAxis, Axis yAxis)
        {
            this.xAxis = xAxis;
            this.yAxis = yAxis;
        }

        #endregion Constructors

        #region PublicMethods
        //this method won't be used, it is being moved to the GraphGenerator, don't call :)
        public void Build(double xMin, double xMax, double xScale, double yMin, double yMax, double yScale)
        {
            double tempWidth = 0;
            double tempHeight = 0;
            double xAxisHeight = 0;
            double xAxisWidth = 0;
            double yAxisHeight = 0;
            double yAxisWidth = 0;

            tempWidth = Math.Abs(xMin) + Math.Abs(xMax);
            xAxisWidth = tempWidth;
            xAxisHeight = 1.0;

            tempHeight = Math.Abs(yMin) + Math.Abs(yMax);
            yAxisHeight = tempHeight;
            yAxisWidth = 1.0;

            //create the x axis
            //xAxis = buildAxis(xAxisWidth, xAxisHeight, xScale);
            //create the y axis
            //yAxis = buildAxis(yAxisWidth, yAxisHeight, yScale);

        }

        public void BuildFromEquation(Equation equation)
        {

        }

        public void setXWidth(double xWidth)
        {

        }

        public void setXHeight(double xHeight)
        {

        }
        #endregion PublicMethods

        #region privateMethods
        

        //private List<GraphInterval> buildListOfIntervals(double intervalWidth, double intervalHeight)
        //{
        //    Point point;
        //    List<GraphInterval> tempIntervals = new List<GraphInterval>();
        //    GraphInterval tempGraphInterval;
        //    //not sure that this is how this will work, i imagine it will be similar to creating the grid
        //    for (int i = 0; i < intervalWidth; i++)
        //    {
        //        for (int j = 0; j < intervalHeight; j++)
        //        {
        //            //this point should be based off of which axis, and what the scale is
        //            //if it's x axis, then y should be 0, and vice versa
        //            point = new Point(i, j);

        //            tempGraphInterval = buildInterval(intervalWidth, intervalHeight, point, new Color());
        //        }
        //    }
        //    return tempIntervals;

        //}

        

        #endregion privateMethods

    }
}
